﻿////#define _CRT_SECURE_NO_WARNINGS 1
////#include <iostream>
////
////using namespace std;
//////
////////double Divide(int a, int b)
////////{
////////	// 当b == 0时抛出异常
////////	if (b == 0)
////////	{
////////		throw "Divide by zero condition!";
////////	}
////////	else
////////	{
////////		return (double)a / (double)b;
////////	}
////////}
////////void Func()
////////{
////////	// 这⾥可以看到如果发⽣除0错误抛出异常，另外下⾯的array和array2没有得到释放。
////////	// 所以这⾥捕获异常后并不处理异常，异常还是交给外⾯处理，这⾥捕获了再重新抛出去。
////////	// 但是如果array2new的时候抛异常呢，就还需要套⼀层捕获释放逻辑，这⾥更好解决⽅案
////////	// 是智能指针，否则代码太戳了
////////	int* array1 = new int[10];
////////	int* array2 = new int[10]; // 抛异常呢
////////	
////////	try
////////	{
////////		int len, time;
////////		cin >> len >> time;
////////		std::cout << Divide(len, time) << endl;
////////	}
////////	catch (...)
////////	{
////////		std::cout << "delete []" << array1 << endl;
////////		std::cout << "delete []" << array2 << endl; delete[] array1;
////////		delete[] array2;
////////		throw; // 异常重新抛出，捕获到什么抛出什么
////////	}
////////	std::cout << "delete []" << array1 << endl;
////////	delete[] array1;
////////	std::cout << "delete []" << array2 << endl;
////////	delete[] array2;
////////}
////////int main()
////////{
////////	try
////////	{
////////		Func();
////////	}
////////	catch (const char* errmsg)
////////	{
////////		std::cout << errmsg << endl;
////////	}
////////	catch (const exception& e)
////////	{
////////		std::cout << e.what() << endl;
////////	}
////////	catch (...)
////////	{
////////		std::cout << "未知异常" << endl;
////////	}
////////	return 0;
////////}
//////
//////
//////#include<thread>
//////
//////// ⼀般⼤型项⽬程序才会使⽤异常，下⾯我们模拟设计⼀个服务的⼏个模块
//////// 每个模块的继承都是Exception的派⽣类，每个模块可以添加⾃⼰的数据
////// 最后捕获时，我们捕获基类就可以
////class Exception
////{
////public:
////	Exception(const string& errmsg, int id)
////		:_errmsg(errmsg)
////		, _id(id)
////	{}
////	virtual string what() const
////	{
////		return _errmsg;
////	}
////	int getid() const
////	{
////		return _id;
////	}
////protected:
////	string _errmsg;
////	int _id;
////};
////class SqlException : public Exception
////{
////public:
////	SqlException(const string& errmsg, int id, const string& sql)
////		:Exception(errmsg, id)
////		, _sql(sql)
////	{}
////	virtual string what() const
////	{
////		string str = "SqlException:";
////		str += _errmsg;
////		str += "->";
////		str += _sql;
////		return str;
////	}
////private:
////	const string _sql;
////};
////
////class CacheException : public Exception
////{
////public:
////	CacheException(const string& errmsg, int id)
////		:Exception(errmsg, id)
////	{}
////	virtual string what() const
////	{
////		string str = "CacheException:";
////		str += _errmsg;
////		return str;
////	}
////};
////class HttpException : public Exception
////{
////public:
////	HttpException(const string& errmsg, int id, const string& type)
////		:Exception(errmsg, id)
////		, _type(type)
////	{}
////	virtual string what() const
////	{
////		string str = "HttpException:";
////		str += _type;
////		str += ":";
////		str += _errmsg;
////		return str;
////	}
////private:
////	const string _type;
////};
////void SQLMgr()
////{
////	if (rand() % 7 == 0)
////	{
////		throw SqlException("权限不足", 100, "select * from name = '张三'");
////	}
////	else
////	{
////		cout << "SQLMgr 调用成功" << endl;
////	}
////}
////
////void CacheMgr()
////{
////	if (rand() % 5 == 0)
////	{
////		throw CacheException("权限不足", 100);
////	}
////	else if (rand() % 6 == 0)
////	{
////		throw CacheException("数据不存在", 101);
////	}
////	else
////	{
////		cout << "CacheMgr 调用成功" << endl;
////	}
////	SQLMgr();
////}
////void HttpServer()
////{
////	if (rand() % 3 == 0)
////	{
////		throw HttpException("请求资源不存在", 100, "get");
////	}
////	else if (rand() % 4 == 0)
////	{
////		throw HttpException("权限不足", 101, "post");
////	}
////	else
////	{
////		cout << "HttpServer调用成功" << endl;
////	}
////	CacheMgr();
////}
//////int main()
//////{
//////	srand(time(0));
//////	while (1)
//////	{
//////		this_thread::sleep_for(chrono::seconds(1));
//////		try
//////		{
//////			HttpServer();
//////		}
//////		catch (const Exception& e) // 这⾥捕获基类，基类对象和派⽣类对象都可以被
//////		{
//////			cout << e.what() << endl;
//////		}
//////		catch (...)
//////		{
//////			cout << "Unkown Exception" << endl;
//////		}
//////		
//////	}
//////	 return 0;
//////
//////}
////
////
////void _SeedMsg(const string& s)
////{
////	if (rand() % 2 == 0)
////	{
////		 throw HttpException("⽹络不稳定，发送失败", 102, "put");
////	}
////	else if (rand() % 7 == 0)
////	{
////		 throw HttpException("你已经不是对象的好友，发送失败", 103, "put");
////	}
////	else
////	{
////		 cout << "发送成功" << endl;
////	}
//// }
////
////void SendMsg(const string & s)
//// {
////
////		// 发送消息失败，则再重试3次
////		for (size_t i = 0; i < 4; i++)
////		{
////			try
////			{
////				_SeedMsg(s);
////				break;
////			}
////			catch (const Exception& e)
////			{
////				// 捕获异常，if中是102号错误，⽹络不稳定，则重新发送
////				// 捕获异常，else中不是102号错误，则将异常重新抛出
////				if (e.getid() == 102)
////				{
////					// 重试三次以后否失败了，则说明⽹络太差了，重新抛出异常
////					if (i == 3)
////						throw;
////					cout << "开始第" << i + 1 << "重试" << endl;
////				}
////				else
////				{
////					throw;
////				}
////			}
////		}
////}
////int main()
////{
////	srand(time(0));
////	string str;
////	while (cin >> str)
////	{
////		try
////		{
////			SendMsg(str);
////		}
////		catch (const Exception& e)
////		{
////			cout << e.what() << endl << endl;
////		}
////		catch (...)
////		{
////			cout << "Unkown Exception" << endl;
////		}
////	}
////	return 0;
////}
//
//
//
//#include <iostream>
//
//template<typename T>
//class SmartPtr
//{
//public:
//	SmartPtr(T* ptr)
//		:_ptr(ptr)
//	{}
//	~SmartPtr()
//	{
//		std::cout << "delete ptr[]" << std::endl;
//		delete[] _ptr;
//	}
//	T* operator*()
//	{
//		return _ptr;
//	}
//	T& operator&()
//	{
//		return *_ptr;
//	}
//	T& operator[](size_t i)
//	{
//		return _ptr[i];
//	}
//private:
//	T* _ptr;
//};
//
//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//			return (double)a / (double)b;
//	}
//}
//using namespace std;
//void Func()
//{
//	// 这⾥使⽤RAII的智能指针类管理new出来的数组以后，程序简单多了
//	SmartPtr<int> sp1 = new int[10];
//	SmartPtr<int> sp2 = new int[10];
//	for (size_t i = 0; i < 10; i++)
//	{
//		sp1[i] = sp2[i] = i;
//	}
//	int len, time;
//	cin >> len >> time;
//	cout << Divide(len, time) << endl;
//}
//int main()
//{
//	try
//	{
//		Func();
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...)
//	{
//		cout << "未知异常" << endl;
//	}
//	return 0;
//}

#include "smart_ptr.h"

using namespace PtrMudule;

struct ListNode
{
	int _data;
	std::weak_ptr<ListNode> _next;
	std::weak_ptr<ListNode> _prev;
	// 这⾥改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
	// 不增加n2的引⽤计数，不参与资源释放的管理，就不会形成循环引⽤了
	/*std::weak_ptr<ListNode> _next;
	std::weak_ptr<ListNode> _prev;*/
	~ListNode()
	{
		std::cout << "~ListNode()" << std::endl;
	}
};
int main()
{
	//Date* d1 = new Date(2025, 3, 15);
	//Date* d2 = new Date(2026, 3, 15);
	///*auto_ptr<Date> p1(d1);
	//auto_ptr<Date> p2(d2);
	//p1 = p2;*/
	//unique_ptr<Date> p1(d1);
	//unique_ptr<Date> p2(std::move(p1));
	std::shared_ptr<ListNode> n1(new ListNode);
	std::shared_ptr<ListNode> n2(new ListNode);
	std::cout << n1.use_count() << std::endl;
	std::cout << n2.use_count() << std::endl;
	n1->_next = n2;
	n2->_prev = n1;
	std::cout << n1.use_count() << std::endl;


}